//! 复合索引实现
//! 
//! 支持多列索引，提供高效的多条件查询

use crate::sql::Value;
use crate::{Error, Result};
use super::btree::BPlusTree;
use super::hash::HashIndex;
use std::collections::HashMap;

/// 复合索引类型
#[derive(Debug, Clone, PartialEq)]
pub enum CompositeIndexType {
    /// B+树复合索引
    BTree,
    /// 哈希复合索引
    Hash,
}

/// 复合索引
#[derive(Debug)]
pub struct CompositeIndex {
    /// 索引名称
    name: String,
    /// 列名列表
    columns: Vec<String>,
    /// 索引类型
    index_type: CompositeIndexType,
    /// 底层索引实现
    index: CompositeIndexImpl,
    /// 统计信息
    stats: CompositeIndexStats,
}

/// 复合索引实现
#[derive(Debug)]
enum CompositeIndexImpl {
    /// B+树实现
    BTree(BPlusTree),
    /// 哈希实现
    Hash(HashIndex),
}

/// 复合索引统计信息
#[derive(Debug, Clone, Default)]
pub struct CompositeIndexStats {
    /// 总条目数
    pub total_entries: usize,
    /// 查找次数
    pub lookup_count: u64,
    /// 插入次数
    pub insert_count: u64,
    /// 删除次数
    pub delete_count: u64,
    /// 范围查询次数
    pub range_query_count: u64,
    /// 前缀查询次数
    pub prefix_query_count: u64,
}

/// 复合键
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct CompositeKey {
    /// 键值列表
    values: Vec<Value>,
}

impl CompositeIndex {
    /// 创建新的复合索引
    pub fn new(
        name: String,
        columns: Vec<String>,
        index_type: CompositeIndexType,
    ) -> Result<Self> {
        if columns.is_empty() {
            return Err(Error::index("复合索引必须至少包含一列".to_string()));
        }
        
        let index = match index_type {
            CompositeIndexType::BTree => {
                CompositeIndexImpl::BTree(BPlusTree::new(100)) // 度数100
            }
            CompositeIndexType::Hash => {
                CompositeIndexImpl::Hash(HashIndex::new(256)) // 256个桶
            }
        };
        
        Ok(Self {
            name,
            columns,
            index_type,
            index,
            stats: CompositeIndexStats::default(),
        })
    }
    
    /// 插入复合键值对
    pub fn insert(&mut self, values: Vec<Value>, row_id: usize) -> Result<()> {
        if values.len() != self.columns.len() {
            return Err(Error::index(format!(
                "复合键长度不匹配: 期望 {}, 实际 {}",
                self.columns.len(),
                values.len()
            )));
        }
        
        let composite_key = CompositeKey::new(values);
        let key_value = self.composite_key_to_value(&composite_key);
        
        match &mut self.index {
            CompositeIndexImpl::BTree(btree) => {
                btree.insert(key_value, row_id)?;
            }
            CompositeIndexImpl::Hash(hash) => {
                hash.insert(key_value, row_id)?;
            }
        }
        
        self.stats.insert_count += 1;
        self.stats.total_entries += 1;
        
        Ok(())
    }
    
    /// 查找复合键
    pub fn lookup(&mut self, values: Vec<Value>) -> Result<Option<usize>> {
        if values.len() != self.columns.len() {
            return Err(Error::index(format!(
                "复合键长度不匹配: 期望 {}, 实际 {}",
                self.columns.len(),
                values.len()
            )));
        }
        
        let composite_key = CompositeKey::new(values);
        let key_value = self.composite_key_to_value(&composite_key);
        
        self.stats.lookup_count += 1;
        
        let result = match &self.index {
            CompositeIndexImpl::BTree(btree) => btree.search(&key_value),
            CompositeIndexImpl::Hash(hash) => hash.lookup(&key_value),
        };
        
        Ok(result)
    }
    
    /// 前缀查找（仅B+树支持）
    pub fn prefix_lookup(&mut self, prefix_values: Vec<Value>) -> Result<Vec<usize>> {
        if prefix_values.len() > self.columns.len() {
            return Err(Error::index("前缀长度不能超过索引列数".to_string()));
        }
        
        self.stats.prefix_query_count += 1;
        
        match &self.index {
            CompositeIndexImpl::BTree(btree) => {
                // 构造前缀范围
                let mut start_values = prefix_values.clone();
                let mut end_values = prefix_values.clone();
                
                // 填充剩余列为最小/最大值
                for _ in prefix_values.len()..self.columns.len() {
                    start_values.push(Value::Null); // 最小值
                    end_values.push(self.max_value()); // 最大值
                }
                
                let start_key = self.composite_key_to_value(&CompositeKey::new(start_values));
                let end_key = self.composite_key_to_value(&CompositeKey::new(end_values));
                
                Ok(btree.range_search(&start_key, &end_key))
            }
            CompositeIndexImpl::Hash(_) => {
                Err(Error::index("哈希索引不支持前缀查询".to_string()))
            }
        }
    }
    
    /// 范围查询（仅B+树支持）
    pub fn range_lookup(
        &mut self,
        start_values: Vec<Value>,
        end_values: Vec<Value>,
    ) -> Result<Vec<usize>> {
        if start_values.len() != self.columns.len() || end_values.len() != self.columns.len() {
            return Err(Error::index("范围查询键长度必须匹配索引列数".to_string()));
        }
        
        self.stats.range_query_count += 1;
        
        match &self.index {
            CompositeIndexImpl::BTree(btree) => {
                let start_key = self.composite_key_to_value(&CompositeKey::new(start_values));
                let end_key = self.composite_key_to_value(&CompositeKey::new(end_values));
                Ok(btree.range_search(&start_key, &end_key))
            }
            CompositeIndexImpl::Hash(_) => {
                Err(Error::index("哈希索引不支持范围查询".to_string()))
            }
        }
    }
    
    /// 删除复合键
    pub fn delete(&mut self, values: Vec<Value>) -> Result<()> {
        if values.len() != self.columns.len() {
            return Err(Error::index(format!(
                "复合键长度不匹配: 期望 {}, 实际 {}",
                self.columns.len(),
                values.len()
            )));
        }
        
        let composite_key = CompositeKey::new(values);
        let key_value = self.composite_key_to_value(&composite_key);
        
        match &mut self.index {
            CompositeIndexImpl::BTree(btree) => {
                btree.delete(&key_value)?;
            }
            CompositeIndexImpl::Hash(hash) => {
                hash.delete(&key_value)?;
            }
        }
        
        self.stats.delete_count += 1;
        if self.stats.total_entries > 0 {
            self.stats.total_entries -= 1;
        }
        
        Ok(())
    }
    
    /// 获取索引名称
    pub fn name(&self) -> &str {
        &self.name
    }
    
    /// 获取列名列表
    pub fn columns(&self) -> &[String] {
        &self.columns
    }
    
    /// 获取索引类型
    pub fn index_type(&self) -> CompositeIndexType {
        self.index_type.clone()
    }
    
    /// 获取统计信息
    pub fn get_stats(&self) -> &CompositeIndexStats {
        &self.stats
    }
    
    /// 清空索引
    pub fn clear(&mut self) {
        match &mut self.index {
            CompositeIndexImpl::BTree(btree) => {
                *btree = BPlusTree::new(100);
            }
            CompositeIndexImpl::Hash(hash) => {
                hash.clear();
            }
        }
        
        self.stats = CompositeIndexStats::default();
    }
    
    /// 获取索引大小
    pub fn size(&self) -> usize {
        self.stats.total_entries
    }
    
    /// 计算内存使用量
    pub fn memory_usage(&self) -> usize {
        match &self.index {
            CompositeIndexImpl::BTree(btree) => btree.memory_usage(),
            CompositeIndexImpl::Hash(hash) => hash.memory_usage(),
        }
    }
    
    /// 将复合键转换为单一值
    fn composite_key_to_value(&self, composite_key: &CompositeKey) -> Value {
        // 简单实现：将所有值序列化为字符串
        let serialized = composite_key.values
            .iter()
            .map(|v| self.value_to_string(v))
            .collect::<Vec<_>>()
            .join("|");
        
        Value::Text(serialized)
    }
    
    /// 将值转换为字符串
    fn value_to_string(&self, value: &Value) -> String {
        match value {
            Value::Integer(i) => format!("i:{}", i),
            Value::Real(f) => format!("f:{}", f),
            Value::Text(s) => format!("s:{}", s),
            Value::Boolean(b) => format!("b:{}", b),
            Value::Null => "n:null".to_string(),
            Value::Timestamp(ts) => format!("t:{}", ts.to_rfc3339()),
            Value::Decimal(d) => format!("d:{}", d),
        }
    }
    
    /// 获取最大值
    fn max_value(&self) -> Value {
        Value::Text("~".to_string()) // 使用波浪号作为最大值
    }
}

impl CompositeKey {
    /// 创建新的复合键
    pub fn new(values: Vec<Value>) -> Self {
        Self { values }
    }
    
    /// 获取键值列表
    pub fn values(&self) -> &[Value] {
        &self.values
    }
    
    /// 获取指定位置的值
    pub fn get(&self, index: usize) -> Option<&Value> {
        self.values.get(index)
    }
    
    /// 获取键的长度
    pub fn len(&self) -> usize {
        self.values.len()
    }
    
    /// 检查是否为空
    pub fn is_empty(&self) -> bool {
        self.values.is_empty()
    }
    
    /// 获取前缀
    pub fn prefix(&self, len: usize) -> CompositeKey {
        let prefix_values = self.values.iter().take(len).cloned().collect();
        CompositeKey::new(prefix_values)
    }
}
